package cz.muni.fi.pa165.languageschool.dao.impl;

import cz.muni.fi.pa165.languageschool.Course;
import cz.muni.fi.pa165.languageschool.Lecture;
import cz.muni.fi.pa165.languageschool.dao.CourseDao;
import java.util.Collections;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * CourseDao implementation using JPA
 *
 * @author Michal Fučík (395624) michal.fuca.fucik(at)gmail.com
 */
public class CourseDaoImpl implements CourseDao {

    final static Logger log = LoggerFactory.getLogger(CourseDaoImpl.class);
    private EntityManager entityManager;

    public CourseDaoImpl() {
    }

    public CourseDaoImpl(EntityManager em) {
        if (em == null) {
            throw new NullPointerException("Argument em was null");
        }
        this.entityManager = em;
    }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public void createCourse(Course course) {
        log.info("***** DAO Course - createCourse: {}", course);
        if (course == null) {
            throw new NullPointerException("Argument course cannot be null.");
        }
        entityManager.persist(course);
    }

    @Override
    public List<Course> getAllCourses() {
        log.info("***** DAO Course - getAllCourses");
        TypedQuery<Course> tq = entityManager.createQuery(
                "SELECT c FROM Course c", Course.class);
        return tq.getResultList();
    }

    @Override
    public Course getCourse(Long id) {
        log.info("***** DAO Course - getCourse: {}", id);
        Course res = null;
        if (id == null) {
            throw new NullPointerException("Argument id cannot be null.");
        }
        return entityManager.find(Course.class, id);
    }

    @Override
    public Course updateCourse(Course course) {
        log.info("***** DAO Course - updateCourse: {}", course);
        if (course == null) {
            throw new IllegalArgumentException("Argument course cannot be null.");
        }

        Course crs = entityManager.find(Course.class, course.getId());
        if (crs == null) {
            throw new IllegalArgumentException("Passed course doesn't exist in database");
        }

        crs.setCode(course.getCode());
        crs.setName(course.getName());
        crs.setLevel(course.getLevel());
        crs.setCourseLanguage(course.getCourseLanguage());
        crs.setRelatedLectures(course.getRelatedLectures());

        entityManager.persist(crs);
        return crs;
    }

    @Override
    public void deleteCourse(Course course) {
        log.info("***** DAO Course - deleteCourse: {}", course);
        if (course == null) {
            throw new NullPointerException("Argument course cannot be null.");
        }

        Course crs = entityManager.find(Course.class, course.getId());
        if (crs == null) {
            throw new IllegalArgumentException("Passed course doesn't exist in database");
        }

        entityManager.remove(crs);
    }

    @Override
    public List<Lecture> getCourseRelatedLectures(Course crs) {
        log.info("***** DAO Course - getCourseRelatedLectures: {}", crs);
        if (crs == null) {
            throw new NullPointerException("Argument crs was null");
        }
        Course cdb = entityManager.find(Course.class, crs.getId());
        if (cdb == null) {
            throw new IllegalArgumentException("Given course doesn't exist in database");
        }
        return Collections.unmodifiableList(cdb.getRelatedLectures());
    }
}
